package com.hm.cms.auto.su;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.hm.cms.auto.su.R.RedisKey;
import com.hm.cms.service.BlacklistService;
import com.hm.cms.service.VisitIpStatisticsService;
import com.hm.common.exception.ErrorCode;
import com.hm.common.redis.jedis.JedisFactory;
import com.hm.common.redis.jedis.su.JedisHandler;
import com.hm.common.redis.jedis.su.JedisHandlerSupport;
import com.hm.common.util.CommonUtil;
import com.hm.common.util.RemoteClientUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * @author shishun.wang
 * @date 2017年10月31日 下午10:52:27
 * @version 1.0
 * @describe
 */
@Slf4j
@Aspect
@Component
public class ControllerAspectHandler {

	@Autowired
	private JedisHandlerSupport jedisHandler;

	@Autowired
	private BlacklistService blacklistService;

	@Autowired
	private VisitIpStatisticsService visitIpStatisticsService;

	@Around("execution(* com.hm.cms.controller.**Controller.*(..))")
	public Object process(ProceedingJoinPoint point) throws Throwable {
		try {
			HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
					.getRequest();

			HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
					.getResponse();
			{
				// 这句话的意思，是让浏览器用utf8来解析返回的数据
				response.setHeader("Content-type", "text/html;charset=UTF-8");
				// 这句话的意思，是告诉servlet用UTF-8转码，而不是用默认的ISO8859
				response.setCharacterEncoding("UTF-8");
			}

			StringBuffer uri = request.getRequestURL();
			String domainName = uri.delete(uri.length() - request.getRequestURI().length(), uri.length()).append("/")
					.toString();

			final String ip = RemoteClientUtil.getPackHost(request);

			// 屏蔽ip地址:
			Object value = jedisHandler.executeCommand(new JedisHandler() {

				@Override
				public Object handler(JedisFactory jedis) {
					return jedis.get(RedisKey.MAX_VISIT_COUNT + ":" + ip);
				}
			});

			if (CommonUtil.isNotEmpty(value)) {
				log.warn("ip访问次数太过频繁:" + domainName);
				response.getWriter().write(ErrorCode.CLIENT_REQUEST_VISIT_FREQUENTLY.describe());
				return null;
			}

			if (blacklistService.existsBlacklistByDomainName(domainName.trim())) {
				log.warn("黑名单域名访问,被阻止:" + domainName);
				response.getWriter().write(ErrorCode.NO_DATA_ACCESS.describe());
				return null;
			}

			visitIpStatisticsService.saveVisitIpStatistics(ip, request.getRequestURL().toString());
		} catch (Exception e) {
			log.error("记录客户端访问ip地址失败", e);
		}
		return point.proceed();
	}
}
